#include "ArrayAccess.h"
#include "../Exceptions.h"
#include "../GeneralVisitor.h"

ArrayAccess::ArrayAccess(TreeNode* iSource, TreeNode* iIndexExpression)
{
    fSource = iSource;
    fIndexExpression = iIndexExpression;
}

ArrayAccess::~ArrayAccess()
{
    delete fSource;
    delete fIndexExpression;
}

void ArrayAccess::CheckVariables(set<string>& oVariables, string iParentName)
{
    this->fSource->CheckVariables(oVariables, iParentName);
    this->fIndexExpression->CheckVariables(oVariables, iParentName);
}

void ArrayAccess::CheckExpressionTypes(map<string, ExpressionType*>& iVarTypes, string iParentName)
{
    this->fSource->CheckExpressionTypes(iVarTypes, iParentName);
    this->fIndexExpression->CheckExpressionTypes(iVarTypes, iParentName);

    ExpressionType* lType = this->fSource->GetType(iVarTypes, iParentName);

    if(lType->fResolveTypeAtRuntime)
    {
        delete lType;
        return;
    }

    string lName = this->fSource->GetVarName();

    if(lType->fType != Array)
    {
        delete lType;
        throw VariableIsNotAnArrayException(lName, iParentName);
    }

    delete lType;
    lType = this->fIndexExpression->GetType(iVarTypes, iParentName);

    if(lType->fResolveTypeAtRuntime)
    {
        delete lType;
        return;
    }

    if(lType->fType != LongInteger && lType->fType != Double && lType->fType != String)
    {
        ValueType lValType = lType->fType;
        delete lType;
        throw InvalidIndexTypeException(iParentName, lValType);
    }

    delete lType;
}

ExpressionType* ArrayAccess::GetType(map<string, ExpressionType*>&, string iParentName)
{
    return new ExpressionType(Unresolved);
}

void ArrayAccess::Accept(GeneralVisitor* iVisitor)
{
    iVisitor->Visit(this);
}
